﻿using System;
using System.Data;
using System.Collections.Generic;
using System.Text;
using SdmxMl.Common;
using SdmxMl.Manager;

namespace SdmxMl.Structure
{
    public class StrSetMapItem : IAnnotationList    
    {
        public string Alias { get; set; }
        public string Source { get; set; }
        public virtual string Target { get; set; }

        #region IAnnotationList Members

        public AnnotationList AnnotationList { get; set; }

        #endregion

        protected void Init()
        {
            Alias = Source = Target = string.Empty;
        }
        public StrSetMapItem()
        {
            AnnotationList = new AnnotationList();
            Init();
        }
        public StrSetMapItem(string s, string t, string a)
        {
            AnnotationList = new AnnotationList();
            Alias = a;
            Source = s;
            Target = t;
        }
        public override string ToString()
        {
            return Source + " - " + Target;
        }

    }


    public class StrSetMapItemList : List<StrSetMapItem>
    {
        public ArtefactRefBase SourceRef { get; set; }

        public ArtefactRefBase TargetRef { get; set; }

        public SdmxArtefactType ArtType { get; private set; }

        public BaseArtefact Info { get; private set; }

        public StrSetMapItemList(SdmxArtefactType art, BaseArtefact ba)
        {
            ArtType = art;
            Info = ba;
        }

        public DataTable GetMapTable()
        {
            DataTable tb = CreateMapTable();

            FlatHierarchicalList fhlSource = null;
            FlatHierarchicalList fhlTarget = null;

            Artefact arSource = null;
            Artefact arTarget = null;
            SmManager sm = ReferenceManager.GetSmContainerImage();

            try
            {
                // Can be not in registry, allows exception
                if (SourceRef.IsFilled)
                    arSource = sm.GetArtefact(ArtType, SourceRef, true);
                if (TargetRef.IsFilled)
                    arTarget = sm.GetArtefact(ArtType, TargetRef, true);
            }
            catch { }

            if (ArtType == SdmxArtefactType.CodeLists)
            {
                if (arSource != null)
                    fhlSource = (arSource as CodeListType).CodeList;
                if (arTarget != null)
                    fhlTarget = (arTarget as CodeListType).CodeList;
            }

            foreach (StrSetMapItem cm in this)
                tb.Rows.Add(new object[] 
            { 
                cm.Source,
                GetCodeText(fhlSource, cm.Source) ,
                cm.Alias,
                cm.Target,
                GetCodeText(fhlTarget, cm.Target) ,
            });

            return tb;
        }

        private string GetCodeText(FlatHierarchicalList fhl, string id)
        {
            ISdmxHierarchyListItem item = null;
            string txt = string.Empty;
            if (fhl != null)
                if ((item = fhl.LocateItem(id)) != null)
                    txt = item.Name.ToString();
            return txt;
        }


        private DataTable CreateMapTable()
        {
            DataTable dataTable = new DataTable();
            dataTable.Columns.Add(new DataColumn("Source", typeof(string)));
            dataTable.Columns.Add(new DataColumn("SourceName", typeof(string)));
            dataTable.Columns.Add(new DataColumn("Alias", typeof(string)));
            dataTable.Columns.Add(new DataColumn("Target", typeof(string)));
            dataTable.Columns.Add(new DataColumn("TargetName", typeof(string)));

            return dataTable;
        }

        public bool IsDefined(StrSetMapItem item)
        {
            foreach (StrSetMapItem cm in this)
                if (cm.Source == item.Source && cm.Target == item.Target)
                    return true;
            return false;

        }
        public void RemoveItem(StrSetMapItem item)
        {
            StrSetMapItem toRemove = null;

            foreach (StrSetMapItem cm in this)
                if (cm.Source == item.Source && cm.Target == item.Target)
                {
                    toRemove = cm;
                    break;
                }
            if (toRemove != null)
                this.Remove(toRemove);

        }

        public List<string> GetTargetArrayForSource(string source)
        {
            List<string> list = new List<string>();

            foreach (StrSetMapItem cm in this)
                if (cm.Source == source)
                    list.Add(cm.Target);
            return list;
        }

        public List<string> GetSourceArrayForTarget(string target)
        {
            List<string> list = new List<string>();

            foreach (StrSetMapItem cm in this)
                if (cm.Target == target)
                    list.Add(cm.Source);
            return list;
        }
    }
}
